<script lang="ts" setup>
import { onMounted, ref, type Ref } from 'vue'

/** Props 类型定义 */
interface ScrollListProps {
  apiFn: (params: Record<string, any>) => Promise<{ data: any[] }>
  params?: Record<string, any>
  pageSize?: number
  height?: number
  loadingText?: string
  noMoreText?: string
  autoLoad?: boolean
}

const props = defineProps<ScrollListProps>()

// 默认值处理
const {
  apiFn,
  params = {},
  pageSize = 10,
  height = 500,
  loadingText = '加载中...',
  noMoreText = '没有更多了',
  autoLoad = true,
} = props

// 状态
const list: Ref<any[]> = ref([])
const pageIndex = ref(1)
const loading = ref(false)
const refreshing = ref(false)
const noMore = ref(false)

/** 加载数据 */
async function loadList(isRefresh = false) {
  if (loading.value)
    return
  loading.value = true

  if (isRefresh) {
    pageIndex.value = 1
    noMore.value = false
  }

  const query = {
    pageIndex: pageIndex.value,
    pageSize,
    ...params,
  }

  try {
    const res = await apiFn(query)
    const data = res?.data || []

    if (pageIndex.value === 1) {
      list.value = data
    }
    else {
      list.value.push(...data)
    }

    if (data.length < pageSize) {
      noMore.value = true
    }
    else {
      pageIndex.value += 1
    }
  }
  catch (err) {
    console.error('列表加载失败', err)
  }
  finally {
    loading.value = false
    if (isRefresh)
      refreshing.value = false
  }
}

/** 下拉刷新 */
function onRefresh() {
  refreshing.value = true
  loadList(true)
}

/** 上拉加载 */
function loadMore() {
  if (!noMore.value) {
    loadList()
  }
}

/** 自动加载 */
onMounted(() => {
  if (autoLoad)
    loadList()
})

/** 对外暴露 */
defineExpose({
  reload: () => {
    pageIndex.value = 1
    noMore.value = false
    list.value = []
    loadList()
  },
})
</script>

<template>
  <scroll-view
    :style="{ height: `${height}px` }"
    scroll-y
    lower-threshold="50"
    :refresher-enabled="true"
    :refresher-triggered="refreshing"
    @scrolltolower="loadMore"
    @refresherrefresh="onRefresh"
  >
    <!-- 列表项 -->
    <template v-if="list.length > 0">
      <view v-for="item in list" :key="item.id">
        <slot :item="item" />
      </view>
    </template>

    <!-- 空状态 -->
    <template v-else-if="!loading && !refreshing">
      <slot name="empty">
        <view class="py-10 text-center text-gray-400">
          暂无数据
        </view>
      </slot>
    </template>

    <!-- 加载中 -->
    <view v-if="loading && !refreshing" class="py-4 text-center text-gray-400">
      {{ loadingText }}
    </view>

    <!-- 没有更多 -->
    <view v-if="noMore && list.length > 0" class="py-4 text-center text-gray-400">
      {{ noMoreText }}
    </view>
  </scroll-view>
</template>
